package com.guigu.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.guigu.domain.Employee;
import com.guigu.domain.Msg;
import com.guigu.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

//    @RequestMapping("/getAllEmp")
    /*public String getAllEmp(@RequestParam(value = "pageNum",defaultValue = "1") Integer pageNum, Model model){
        //引入PageHelper分页插件
        //在查询之前只需要调用，传入页码，以及每页的大小
        ///获取第1页，5条内容，默认查询总数count
        PageHelper.startPage (pageNum,5);
//        只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询（Select）方法会被分页。
        List<Employee> emps = employeeService.getAllEmp ();
        //用PageInfo对结果进行包装
        //导航页码数  navigatePages
        PageInfo pageInfo = new PageInfo (emps,5);
        model.addAttribute ("pageInfo",pageInfo);
        return "list";
    }*/

    @RequestMapping("/getAllEmp")
    @ResponseBody
    public Msg getAllEmpWithJson(@RequestParam(value = "pageNum",defaultValue = "1") Integer pageNum){
        //引入PageHelper分页插件
        //在查询之前只需要调用，传入页码，以及每页的大小
        ///获取第1页，5条内容，默认查询总数count
        PageHelper.startPage (pageNum,5);
//        只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询（Select）方法会被分页。
        List<Employee> emps = employeeService.getAllEmp ();
        //用PageInfo对结果进行包装
        //导航页码数  navigatePages
        PageInfo pageInfo = new PageInfo (emps,5);
        return Msg.success ().add ("pageInfo",pageInfo);
    }

    /*
    RESTFUL 风格URI
    path="/emp"      POST    保存员工
    path="/emp{id}"  GET    查询员工
    path="/emp{id}"  PUT    修改员工
    path="/emp{id}"  DELETE    删除员工
     */

    /**
     * 保存员工
     * 1、支持JSR303校验
     * 2、导入Hibernate-Validator jar
     * @param employee
     * @return
     */
    @RequestMapping(path="/emp",method = RequestMethod.POST)
//    @PostMapping
    @ResponseBody
    public Msg addEmpWithJson(@Valid Employee employee, BindingResult result){
        if(result.hasErrors ()){
            //校验失败，应该返回失败，在模态框中显示校验失败的错误信息
            Map<String,String> map = new HashMap<> ();
            List<FieldError> fieldErrors = result.getFieldErrors ();
            for (FieldError fieldError:fieldErrors){
                System.out.println (fieldError.getField ());  //字段名称
                System.out.println (fieldError.getDefaultMessage ());  //提示信息
                map.put (fieldError.getField (),fieldError.getDefaultMessage ());
            }
            return Msg.fail ().add ("errorFields",map);
        }
        employeeService.addEmp (employee);
        return Msg.success ();
    }

    /**
     * 如果直接发送ajax=PUT形式的请求
     *    封装的数据
     *    Employee
     *    Employee{empId=1043, empName='null', gender='null', email='null', dId=null, department=null}
     *
     * 问题：
     *     请求体中有数据，但是Employee对象封装不上，
     *     执行的SQL语句为：update tab_emp where emp_id = #{empId,jdbcType=INTEGER}  （错误语法）
     *
     * 问题：
     *  Tomcat：
     *      1、将请求体中的数据，封装一个map,
     *      2、request.getParameter("empId")就会从这个map中取值。
     *      3、SpringMVC封装POJO对象的时候
     *                  会把POJO中每个属性的值，request.getParameter("属性名")  //PUT方式取不到，只有POST能取到
     *
     * Ajax发送PUT请求引发的问题：
     *      PUT请求：请求体中的数据，request.getParameter("属性名")拿不到
     *      Tomcat一看是PUT不会封装请求体的数据到map，只有POST形式的请求才封装请求体为map
     *      tomcat源码中：org.apache.catalina.connector.Request和org.apache.catalina.connector.Connector两个类中进行了判断，博客详解
     *
     * 解决方案：
     *      我们要能支持直接发送PUT请求之类的请求还要封装请求体中的数据
     *      1.在web.xml上配置HttpPutFormContentFilter过滤器
     *      2.它的作用：将请求体中的数据解析包装成一个map
     *      3.request被重新包装，request.getParameter()被重写，就会从封装得到map中去取
     *
     *
     * 根据id查询员工信息
     * @param empId
     * @return
     */
    @RequestMapping(path = "/emp/{empId}",method = RequestMethod.GET)
    @ResponseBody
    public Msg getEmp(@PathVariable("empId") Integer empId){
        Employee emp = employeeService.getEmp (empId);
        return Msg.success ().add ("emp",emp);
    }

    @RequestMapping(path = "/emp/{empId}",method = RequestMethod.PUT)  //{empId} 要与封装到的Employee对象的属性 empId对应，才能封装
    @ResponseBody
    public Msg updateEmp(Employee employee){
//        System.out.println (employee);
        employeeService.updateEmp (employee);
        return Msg.success ();
    }

    /**
     * 单个删除和批量删除二合一
     * 单个  1
     * 批量  1-2-3
     * @param empIds
     * @return
     */
    @RequestMapping(path = "/emp/{empIds}",method = RequestMethod.DELETE)
    @ResponseBody
    public Msg delEmp(@PathVariable String empIds){
        if(empIds.contains ("-")){
            //包含 多个empId 批量删除
            List<Integer> ids = new ArrayList<> ();
            String[] str_ids = empIds.split ("-");
            for (int i = 0; i < str_ids.length; i++) {
                int empId = Integer.parseInt (str_ids[i]);
                ids.add (empId);
            }
            employeeService.batchDelEmp(ids);
        }else {
            //单个删除
            int empId = Integer.parseInt (empIds);
            employeeService.delEmp (empId);
        }
        return Msg.success ();
    }

    @RequestMapping(path = "/checkEmpName")
    @ResponseBody
    public Msg checkEmpName(String empName){
        Employee empByName = employeeService.getEmpByName (empName);
        if (empByName!=null){
            return Msg.fail ();
        }else {
            return Msg.success ();
        }
    }

}
